using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Criterion;
using Didsoft.DataAccess.NHibernate;
using Didsoft.DataAccess.NHibernate.Extensions;
using Didsoft.DataAccess.Contracts;
using Boa.HD.AccesoDatos.Entidades;
using Boa.HD.AccesoDatos.Contratos;
using Boa.HD.AccesoDatos.Entidades.DTO;
using Boa.HD.AccesoDatos.Entidades.DTO.Reportes;

namespace Boa.HD.AccesoDatos.Contexto
{
   public class HD_HistoriaProblemaAsistidoAccesoDatos : DataAccessBase<HD_HistoriaProblemaAsistido>, IHD_HistoriaProblemaAsistidoAccesoDatos
   {
     public HD_HistoriaProblemaAsistidoAccesoDatos()
     {
     }
     
     /// <summary>
     /// Devuelve una lista IList<HD_HistoriaProblemaAsistido> con todas las ocurrencias encontradas, en base a filtro.
     /// </summary>
     /// <param name="filtro"></param>
     /// <returns></returns>
     public IList<HD_HistoriaProblemaAsistido> BuscarPorFiltro(string filtro)
     {
             ICriteria criteria = Session.CreateCriteria(typeof(HD_HistoriaProblemaAsistido));
             criteria.Add(Expression.Like("NombrePropiedad", filtro+"%")); 
             return criteria.List<HD_HistoriaProblemaAsistido>();
     }

     public void Evitar(HD_HistoriaProblemaAsistido entidad)
     {
         Session.Evict(entidad);
     }

     public IList<HD_HistoriaProblemaAsistido> FiltrarPorTecnico(int Prioridad, bool IncluirCerrados, bool IncluirSolucionados, string filtro)
     {        
         string hql = @"from HD_HistoriaProblemaAsistido hpa 
                        where hpa.AsignacionTecnicoProblema.Tecnico.Nombre like :filtro
                              AND (hpa.PrioridadCalculada = :Prioridad OR :Prioridad = 0 )
                              AND HistorialProblemaPadre is NULL
                         order by hpa.PrioridadCalculada ASC";

         var query = Session.CreateQuery(hql);
         query.SetAnsiString("filtro", filtro+"%");
         //query.SetBoolean("IncluirCerrados", IncluirCerrados);
         //query.SetBoolean("IncluirSolucionados", IncluirSolucionados);
         query.SetInt32("Prioridad", Prioridad);         
        // IList<HD_HistoriaProblemaAsistido> datas = query.List<HD_HistoriaProblemaAsistido>();
         
        //foreach (var item in datas)
        //{
        //    Session.Evict(item);
        //}
        //return datas;
         return query.List<HD_HistoriaProblemaAsistido>();
     }


     public HD_HistoriaProblemaAsistido ObtenerUltimoPorGuidSolicitudAsistencia(string guid)
     {
         string hql = @"from HD_HistoriaProblemaAsistido hpa                             
                        where hpa.SolicitudAsistencia.GuidSolicitudAsistencia = :guid order by hpa.Id desc";
         var query = Session.CreateQuery(hql).SetMaxResults(1);
         query.SetAnsiString("guid", guid);
         HD_HistoriaProblemaAsistido result = query.UniqueResult<HD_HistoriaProblemaAsistido>();
         Session.Evict(result);
         return result;
     }


     public IList<HD_HistoriaProblemaAsistido> ListaUltimosNodosDeProblema(int EmpleadoBOAId)
     {
         string sql = @"declare @HistoriaId int,
                                @EmpleadoTecnicoId int = :EmpleadoBOAId
                        declare @HistoriaResumen table (HistoriaRaiz int, HistoriaPadre int, HistoriaId int) 

                        DECLARE HistoriasCursor CURSOR
                        FOR 
                        SELECT HistoriaProblemaAsistidoId 
                        from HD_HistoriaProblemaAsistido  hpa
                        inner join HD_AsignacionTecnicoProblema atp on atp.AsignacionTecnicoProblemaId = hpa.AsignacionTecnicoProblemaId
                        inner join HD_Tecnico t on t.TecnicoId = atp.TecnicoId
                        where hpa.HistorialProblemaPadreId is null and t.EmpleadoId = @EmpleadoTecnicoId

                        OPEN HistoriasCursor
                        FETCH HistoriasCursor INTO @historiaId	
                        WHILE @@FETCH_STATUS = 0
                        BEGIN
		                        WITH Historial (HistorialProblemaPadreId, HistoriaProblemaAsistidoId)
		                        AS
		                        (
			                          SELECT HistorialProblemaPadreId, HistoriaProblemaAsistidoId
				                        FROM HD_HistoriaProblemaAsistido
				                        WHERE HistoriaProblemaAsistidoId = @historiaId
			                        UNION ALL
		                        --RECURSIVIDAD
			                        SELECT   hpa.HistorialProblemaPadreId, hpa.HistoriaProblemaAsistidoId
				                        FROM HD_HistoriaProblemaAsistido AS hpa
				                        INNER JOIN Historial AS tmp
					                        ON tmp.HistoriaProblemaAsistidoId = hpa.HistorialProblemaPadreId
		                        )
		                        -- Desplegar ResultSet
		                        insert into @HistoriaResumen
		                        SELECT top 1 @historiaId, HistorialProblemaPadreId, HistoriaProblemaAsistidoId FROM Historial order by HistoriaProblemaAsistidoId desc;
	    
	    	
		                        FETCH HistoriasCursor INTO @historiaId
                        END

                        CLOSE HistoriasCursor
                        DEALLOCATE HistoriasCursor 

                        select hpa.* 
                        from  @HistoriaResumen hr
                        inner join HD_HistoriaProblemaAsistido hpa on hpa.HistoriaProblemaAsistidoId = hr.HistoriaId
                        order by hpa.PrioridadCalculada, hpa.FechaRegistro asc
                              ";

         var query = Session.CreateSQLQuery(sql).AddEntity(typeof(HD_HistoriaProblemaAsistido));
         query.SetInt32("EmpleadoBOAId", EmpleadoBOAId);
         return query.List<HD_HistoriaProblemaAsistido>();
     }


     public IList<DtoReporteHistorialProblema> GetSeguimientoProblema(int HistoriaProblemaId)
     {
         string sql = @"declare @HistoriaId int = :HistoriaProblemaId ;

                        with	temp(HistoriaId,  HistoriaProblemaAsistidoId, HistorialProblemaPadreId, FechaRegistro, Descripcion,  PrioridadCalculada, Espacio, EstadoTrabajo,Solucionado, Cerrado) as
                        (
                            select		@HistoriaId,
                                        hpa.HistoriaProblemaAsistidoId,
                                        hpa.HistorialProblemaPadreId,
                                        hpa.FechaRegistro,
                                        convert(varchar(500),hpa.DescripcionHistoria),
                                        --convert(varchar(5000),hpa.DescripcionHistoria),
                                        case hpa.PrioridadCalculada when 1 then 'Muy Alta' when 2 then 'Alta' when 3 then 'Media' else 'Baja' end ,
                                        CONVERT(varchar(100), '    '),
                                        et.Nombre,
                                        hpa.Solucionado,
                                        hpa.Cerrado			
                            from		HD_HistoriaProblemaAsistido hpa
                            inner join HD_EstadoTrabajo et on et.EstadoTrabajoId = hpa.estadoTrabajoId
                            where hpa.HistoriaProblemaAsistidoId = @HistoriaId
                            union all
                            select		@HistoriaId,
                                        f.HistoriaProblemaAsistidoId,
                                        f.HistorialProblemaPadreId,
                                        f.FechaRegistro,
                                        --CONVERT(varchar(500), t.Espacio +' >> '+f.DescripcionHistoria),
                                        CONVERT(varchar(500), f.DescripcionHistoria+' '+isnull(' - '+f.DescripcionSolucion,'') +' '+ isnull(' - '+f.MotivoCambioEstado,'')) ,
                                        case f.PrioridadCalculada when 1 then 'Muy Alta' when 2 then 'Alta' when 3 then 'Media' else 'Baja' end ,
                                        CONVERT(varchar(100), t.Espacio+'    '),
                                        et.Nombre NombreEstadoTrabajo,
                                        f.Solucionado,
                                        et.EsCerrado
                            from		HD_HistoriaProblemaAsistido f
                            inner join	temp t on t.HistoriaProblemaAsistidoId = f.HistorialProblemaPadreId
                            inner join  HD_EstadoTrabajo et on et.EstadoTrabajoId = f.EstadoTrabajoId
                        )

                        select	t.HistoriaProblemaAsistidoId,
                                t.HistorialProblemaPadreId,
                                t.FechaRegistro,
                                t.Descripcion, 
                                t.PrioridadCalculada,
                                t.EstadoTrabajo,  
                                t.Solucionado,
                                t.Cerrado,
                                sa.NombreSolicitante,
                                DescripcionPorUsuario = hpa.DescripcionProblema,
                                NombreProblema = dp.Nombre,
                                DescripcionProblema = dp.Descripcion


                        from	temp t
                        inner join HD_HistoriaProblemaAsistido hpa on hpa.HistoriaProblemaAsistidoId = t.HistoriaId
                        inner join HD_SolicitudAsistencia sa on sa.SolicitudAsistenciaId = hpa.SolicitudAsistenciaId
                        inner join HD_DefinicionProblema dp on dp.DefinicionProblemaId = sa.DefinicionProblemaId";

         var query = Session.CreateSQLQuery(sql);
         query.SetInt32("HistoriaProblemaId", HistoriaProblemaId);
         return query.ListBeanTransformer<DtoReporteHistorialProblema>();     
     }



     public IList<DtoResumenHistoraProblema> GetResumenHistoriaProblema(string filtro, int EstadoTrabajoId, int Prioridad)
     {

         string sql = @" 
                    declare @EstadoTrabajoId int = :EstadoTrabajoId, --  All = -1
                            @Prioridad int = :Prioridad, --  All = -1,
                            @Filtro varchar(50) = :filtro,
        
                            @HistoriaId int

                    declare @HistoriaResumen table (HistoriaRaiz int, HistoriaPadre int, HistoriaId int) 

                    DECLARE HistoriasCursor CURSOR
                    FOR 
                    SELECT HistoriaProblemaAsistidoId 
                    from HD_HistoriaProblemaAsistido  hpa
                    inner join HD_AsignacionTecnicoProblema atp on atp.AsignacionTecnicoProblemaId = hpa.AsignacionTecnicoProblemaId
                    inner join HD_Tecnico t on t.TecnicoId = atp.TecnicoId
                    where hpa.HistorialProblemaPadreId is null --and hpa.HistoriaProblemaAsistidoId = @HistoriaId

                    OPEN HistoriasCursor
                    FETCH HistoriasCursor INTO @historiaId	
                    WHILE @@FETCH_STATUS = 0
                    BEGIN
                            WITH Historial (HistorialProblemaPadreId, HistoriaProblemaAsistidoId)
                            AS
                            (
                                  SELECT HistorialProblemaPadreId, HistoriaProblemaAsistidoId
                                    FROM HD_HistoriaProblemaAsistido
                                    WHERE HistoriaProblemaAsistidoId = @historiaId
                                UNION ALL
                            --RECURSIVIDAD
                                SELECT   hpa.HistorialProblemaPadreId, hpa.HistoriaProblemaAsistidoId
                                    FROM HD_HistoriaProblemaAsistido AS hpa
                                    INNER JOIN Historial AS tmp
                                        ON tmp.HistoriaProblemaAsistidoId = hpa.HistorialProblemaPadreId
                            )
                            -- Desplegar ResultSet
                            insert into @HistoriaResumen
                            SELECT top 1 @historiaId, HistorialProblemaPadreId, HistoriaProblemaAsistidoId FROM Historial order by HistoriaProblemaAsistidoId desc;


                            FETCH HistoriasCursor INTO @historiaId
                    END

                    CLOSE HistoriasCursor
                    DEALLOCATE HistoriasCursor 


                    select 
		                    HistoriaProblemaAsistidoId = hr.HistoriaRaiz,
		                    HistorialProblemaAsistidoUltimo = hr.HistoriaId,
		                    hpaRaiz.FechaRegistro,
		                    FechaUltimaAtencion = hpaUltimo.FechaRegistro,
		                    ProblemaNombre = dpUltimo.Nombre,
		                    ProblemaDescripcion = dpUltimo.Descripcion,
		                    NombreSolicitante = REPLACE(REPLACE(NombreSolicitante,'<<','-'),'>>',''),
                            etUltimo.EstadoTrabajoId,
		                    EstadoTrabajo =  etUltimo.Nombre,
		                    hpaUltimo.PrioridadCalculada,
		                    hpaRaiz.DescripcionHistoria,
                            MotivoCambioEstado = ''

                    from @HistoriaResumen hr
                    inner join HD_HistoriaProblemaAsistido hpaRaiz on hpaRaiz.HistoriaProblemaAsistidoId = hr.HistoriaRaiz

                    inner join HD_HistoriaProblemaAsistido hpaUltimo on hpaUltimo.HistoriaProblemaAsistidoId = hr.HistoriaId
                    inner join HD_SolicitudAsistencia saUltimo on saUltimo.SolicitudAsistenciaId = hpaUltimo.SolicitudAsistenciaId
                    inner join HD_DefinicionProblema dpUltimo on dpUltimo.DefinicionProblemaId = saUltimo.DefinicionProblemaId
                    inner join HD_EstadoTrabajo etUltimo on etUltimo.EstadoTrabajoId = hpaUltimo.EstadoTrabajoId

                    where (hpaUltimo.PrioridadCalculada = @Prioridad OR @Prioridad = -1) AND
	                      (etUltimo.EstadoTrabajoId = @EstadoTrabajoId OR @EstadoTrabajoId = -1) AND
	                      saUltimo.NombreSolicitante like @Filtro";

         var query = Session.CreateSQLQuery(sql);
         query.SetInt32("EstadoTrabajoId", EstadoTrabajoId);
         query.SetInt32("Prioridad", Prioridad);
         query.SetAnsiString("filtro", filtro + "%");

         return query.ListBeanTransformer<DtoResumenHistoraProblema>();
     }

    


   }
}

